package com.geese.module.common.controller;

import com.aliyun.oss.model.PolicyConditions;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.geese.common.BaseController;
import com.geese.common.oss.OssClientManager;
import com.geese.exception.BusinessException;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;

/**
 * Created by yefangyi
 */
@Controller
@RequestMapping(value = "/aliyun")
@Scope("prototype")
public class AliyunController extends BaseController{

	@Value("${oss_dir}")
	private String dir ;
	@Value("${oss_bucket}")
    private String bucket;
	@Value("${oss_region}")
	private String region ;
	@Value("${oss_sts_version}")
	private String stsApiVersion;
	@Value("${oss_sts_accessKey}")
	private  String accessKeyId;
	@Value("${oss_sts_secretKey}")
	private String accessKeySecret;
	@Value("${oss_sts_roleArn}")
	private String roleArn;
	@Value("${oss_sts_roleSessionName}")
	private String roleSessionName;

	@Autowired
	private OssClientManager ossClientManager;

    @ResponseBody
    @GetMapping(value = "/oss/ticket")
    public String getTicket(){
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
		return response(ossClientManager.getPolicy(bucket, dir, policyConds));
    }

    /**
     * 获取sts权限凭证
     * @return
     */
    @ResponseBody
    @GetMapping("/sts/token")
    public String getStsToken() {
        String policy = "{\n" +
                "    \"Version\": \"1\", \n" +
                "    \"Statement\": [\n" +
                "        {\n" +
                "            \"Action\": [\n" +
                "                \"oss:*\"\n" +
                "            ], \n" +
                "            \"Resource\": [\n" +
                "                \"acs:oss:*:*:*\" \n" +
                "            ], \n" +
                "            \"Effect\": \"Allow\"\n" +
                "        }\n" +
                "    ]\n" +
                "}";
        ProtocolType protocolType = ProtocolType.HTTPS;
        try {
            final AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret,
                    roleArn, roleSessionName, policy, protocolType);
            Map<String, Object> result = Maps.newHashMap();
            result.put("expiration", response.getCredentials().getExpiration());
            result.put("accessKeyId", response.getCredentials().getAccessKeyId());
            result.put("accessKeySecret", response.getCredentials().getAccessKeySecret());
            result.put("securityToken", response.getCredentials().getSecurityToken());
            return response(result);
        } catch (ClientException e) {
            System.out.println("Failed to get a token.");
            System.out.println("Error code: " + e.getErrCode());
            System.out.println("Error message: " + e.getErrMsg());
            throw new BusinessException(120054);
        }
    }

    /**
     * 请求阿里获取凭证
     * @param accessKeyId
     * @param accessKeySecret
     * @param roleArn
     * @param roleSessionName
     * @param policy
     * @param protocolType
     * @return
     * @throws ClientException
     */
    private AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret,
                                          String roleArn, String roleSessionName, String policy,
                                          ProtocolType protocolType) throws ClientException {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion(stsApiVersion);
            request.setMethod(MethodType.POST);
            request.setProtocol(protocolType);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            // 发起请求，并得到response
            final AssumeRoleResponse response = client.getAcsResponse(request);

            return response;
        } catch (ClientException e) {
            throw e;
        }
    }
}
